#include <net/if.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <net/ethernet.h> /* the L2 protocols */
#include <netinet/ether.h>

int main()
{
	int fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP));
	if (fd < 0) {
		perror("socket");
		exit(0);
	}
	struct sockaddr_ll lladdr;
	memset(&lladdr, 0, sizeof(lladdr));
	lladdr.sll_family = AF_PACKET;
	lladdr.sll_protocol = htons(ETH_P_ARP);
	lladdr.sll_ifindex = if_nametoindex("br0");

	if (bind(fd, (void *)&lladdr, sizeof(lladdr)) < 0) {
		perror("bind");
		exit(0);
	}

	//send
	memset(&lladdr, 0, sizeof(lladdr));
	lladdr.sll_family = AF_PACKET;
	ether_aton_r("ff:ff:ff:ff:ff:ff", (void *)lladdr.sll_addr);
	lladdr.sll_halen = ETH_ALEN;
	lladdr.sll_ifindex = if_nametoindex("br0");
	lladdr.sll_protocol = htons(ETH_P_ARP);

	struct ether_arp arp;
	memset(&arp, 0, sizeof(arp));
	arp.arp_hrd = htons(ARPHRD_ETHER);
	arp.arp_pro = htons(ETH_P_IP);
	arp.arp_hln = ETH_ALEN;
	arp.arp_pln = 4;
	arp.arp_op = htons(ARPOP_REQUEST);

	ether_aton_r("B8:BA:69:00:00:01", (void *)arp.arp_sha);
	inet_pton(AF_INET, "0.0.0.0", arp.arp_spa);
	inet_pton(AF_INET, "192.168.10.1", arp.arp_tpa);

	if (sendto(fd, &arp, sizeof(arp), 0, (void *)&lladdr, sizeof(lladdr)) < 0) {
		perror("send");
		exit(0);
	}

	//recv
	int len = 0;
	struct ether_arp recvarp;
	char hname[INET_ADDRSTRLEN];
	while ((len = recv(fd, &recvarp, sizeof(recvarp), 0)) > 0) {
		printf("\n*******************************\n");
		printf("recv %s arp pkt\n", recvarp.arp_op == htons(ARPOP_REPLY) ? "replay" : "request");
		printf("sender=%s %s\n", ether_ntoa((void *)recvarp.arp_sha), inet_ntop(AF_INET, recvarp.arp_spa, hname, sizeof(hname)));
		printf("target=%s %s\n", ether_ntoa((void *)recvarp.arp_tha), inet_ntop(AF_INET, recvarp.arp_tpa, hname, sizeof(hname)));
		if (memcmp(recvarp.arp_spa, arp.arp_tpa, 4) == 0) {
			printf("get replay\n");
		}
	}

	return 0;
}
